package compareResult.datasetCompare;

import com.supermap.data.*;
import com.supermap.mapping.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
//import com.supermap.realspace.Feature3Ds;

public class EqualAssert {

	/**
	 * 判断两个值是否相等，可对比数组、String及值型对象
	 * 
	 * @param object1
	 * @param object2
	 * @param delta2
	 * @author wangdh
	 */
	public static boolean isValueEqual(Object object1, Object object2,
			double delta2) {
		if (object1 == null && object2 == null)
			return true;
		if (object1 == null || object2 == null)
			return false;
		try {
			Array.getLength(object1);
			boolean b = true;
			for (int i = 0; i < Array.getLength(object1); i++) {
				b = b
						&& isValueEqual(Array.get(object1, i), Array.get(
								object2, i));
			}
			return b;
		} catch (IllegalArgumentException e1) {
			String string1 = object1.toString().trim();
			String string2 = object2.toString().trim();
			if ((string1 == null && string2.equals(""))
					|| (string1.equals("") && string2 == null)) {
				return true;
			}
		
			try {
				double d1 = Double.valueOf(string1);
				double d2 = Double.valueOf(string2);
				double delta1=0.0;
				if (Math.abs(d1 - d2) > delta2){
					//修改精度 modified by xuling 2010.11.15
					if(string1.indexOf("E") != -1){
						String[] temp1 = string1.split("E");
						String[] temp2 = string2.split("E");
						if(temp1[1].length()>temp2[1].length())
						{
							String osName = System.getProperty("os.name").toLowerCase();
							if (osName.startsWith("win"))  //如果是 win系统的测试 ，则修改精度为（精度较短的小数的精度），如果是其他平台，则修改精度为小数点后6位。
							{
							delta1 = 2 * Math.pow(10, Integer.parseInt(
									temp1[1]) - temp2[0].length() + 2);
							}
							else
								delta1=0.000001;
						}
						else
						{
							String osName = System.getProperty("os.name").toLowerCase();
							if (osName.startsWith("win"))
							{
								delta1 = 2 * Math.pow(10, Integer.parseInt(
								temp2[1]) - temp1[0].length() + 2);
							}
							else
								delta1=0.000001;
						}
						
					} else if(string1.indexOf(".") != -1){
						String[] temp1 = string1.split("\\.");
						String[] temp2 = string2.split("\\.");
						if(temp1[1].length()>temp2[1].length())
						{
							
							String osName = System.getProperty("os.name").toLowerCase();
							if (osName.startsWith("win"))
							{
								delta1 = 2 * Math.pow(10,-temp2[1].length()+1);
							}
							
							else
								delta1=0.000001;
						}
						else
						{
							String osName = System.getProperty("os.name").toLowerCase();
							if (osName.startsWith("win"))
							{
								delta1 = 2 * Math.pow(10,-temp1[1].length()+1); 
							}
							else
								delta1=0.000001;	
						
					    }
					}
					if (Math.abs(d1 - d2) > delta1){
						return false;
					}
				}
			} catch (NumberFormatException e) {
				if (!string1.equals(string2))
					return false;
			}
			return true;
		}
	}

	public static boolean isValueEqual(Object object1, Object object2) {

		return isValueEqual(object1, object2, delta);

	}

	public static boolean isValuesEqual(Object[] objects1, Object[] objects2,
			double delta) {

		if (objects1 == null && objects2 == null)
			return true;

		if (objects1 == null || objects2 == null)
			return false;

		if (objects1.length != objects2.length)
			return false;

		int count = objects1.length;

		// 按需要看要不要排序

		for (int i = 0; i < count; i++) {
			Object object1 = objects1[i];
			Object object2 = objects1[i];
			if (!isValueEqual(object1, object2))
				return false;
		}

		return true;

	}

	public static boolean isValuesEqual(Object[] objects1, Object[] objects2) {

		return isValuesEqual(objects1, objects2, delta);

	}

	public static boolean isArrayEqual(ArrayList arrayList1,
			ArrayList arrayList2) {

		if (arrayList1 == null && arrayList2 == null)
			return true;

		if (arrayList1 == null || arrayList2 == null)
			return false;

		if (arrayList1.size() != arrayList2.size())
			return false;

		int size = arrayList1.size();

		for (int i = 0; i < size; i++) {
			if (!isValueEqual(arrayList1.get(i), arrayList2.get(i)))
				return false;
		}

		return true;
	}
 
	public static boolean isImageEqual(String filepath1, String filepath2) {
		try {
			return Metric.comparePic(filepath1, filepath2);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
//		// 请不要屏蔽此函数，如果需要新实现，请另写一个重载函数
//		if (filepath1.equals(filepath2)) {
//			return true;
//		}
//		long length = 0;
//
//		File f1 = new File(filepath1);
//		File f2 = new File(filepath2);
//
//		try {
//
//			ImageInputStreamImpl iisi1 = new FileImageOutputStream(f1);
//			ImageInputStreamImpl iisi2 = new FileImageOutputStream(f2);
//
//			if (iisi1.length() != iisi2.length()) {
//				return false;
//			} else
//				length = iisi1.length();
//
//			for (long i = 0; i < length; i++) {
//				iisi1.seek(i);
//				iisi2.seek(i);
//				if (iisi1.read() != iisi2.read()) {
//					System.out.println("图片对比，第 " + i + " 点比较失败");
//					return false;	
//				}
//				
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			return false;
//		}
//
//		return true;
	}
	
	// 只采用精确对比
	public static boolean isImageEqual2(String filepath1, String filepath2) {
		try {
			return Metric.comparePic2(filepath1, filepath2);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	// add by wangna, 2010.05.23
	// 图片对比失败后是否把对比失败的预期图片和实际图片拷贝到新的目录，以便人工确认图片的不同之处
	public static boolean isImageEqual(String filepath1, String filepath2, boolean bCopyDiffPic) {
        boolean bResult = isImageEqual(filepath1, filepath2);
        if (bCopyDiffPic && !bResult) {
            copyDiffPictureToSameDir(filepath1, filepath2);
        }
        return bResult;
	}
	
	// 图片对比失败后是否把对比失败的预期图片和实际图片拷贝到新的目录，以便人工确认图片的不同之处
	public static boolean isImageEqual2(String filepath1, String filepath2, boolean bCopyDiffPic) {
        boolean bResult = isImageEqual2(filepath1, filepath2);
        if (bCopyDiffPic && !bResult) {
            copyDiffPictureToSameDir(filepath1, filepath2);
        }
        return bResult;
	}
	
	/// <summary>把对比失败的预期图片和实际图片拷贝到新的目录，以便人工确认图片的不同之处</summary>
    /// <param name="strExpectPic">预期图片全路径名</param>
    /// <param name="strActualPic">实际图片全路径名</param>
    /// <returns>void</returns>
    public static void copyDiffPictureToSameDir(String strExpectPicName, String strActualPicName) {
		String strOSName = System.getProperty("os.name");
        String strDestPicPath;
        String strPathSeparator = "\\"; // 路径分隔符
        
		if(strOSName.toLowerCase().startsWith("win")){
			//windows使用下面路径
			strDestPicPath = "D:/DiffPictureDir/Java/";
		} else {
			strDestPicPath = "/home/map/DiffPictureDir/Java/";		
			strPathSeparator = "/";
		}

        try {
            // 获取图片所在的文件夹名
        	File fileExpect = new File(strExpectPicName);
            String strExpectPicPath = fileExpect.getParent();
            int nIndex = strExpectPicPath.lastIndexOf(strPathSeparator) + 1;
            strDestPicPath = strDestPicPath + strExpectPicPath.substring(nIndex);
            String strPicNameWithExtension = fileExpect.getName();
            nIndex = strPicNameWithExtension.indexOf(".");
            String strPicName = strPicNameWithExtension.substring(0, nIndex);
            String strExtension = strPicNameWithExtension.substring(nIndex);
            // 图片拷贝目标文件夹 
            strDestPicPath = strDestPicPath + "/" + strPicName + "/";
            FileInputStream fileInputStream = new FileInputStream(strExpectPicName);
            BufferedInputStream in = new BufferedInputStream(fileInputStream);
            File file = new File(strDestPicPath + strPicName + "_Expect" + strExtension);
            if (!file.getParentFile().exists()) {
				File parent = file.getParentFile().getAbsoluteFile();
				if (parent.mkdirs())
					System.out.println("文件夹不存在，创建...."
							+ parent.getAbsolutePath());
			}

            FileOutputStream fileOutputSteam = new FileOutputStream(file);
            BufferedOutputStream out = new BufferedOutputStream(fileOutputSteam);
            
            byte[] buf = new byte[1024];
            int nLen = in.read(buf);
            while (nLen != -1) {
            	out.write(buf, 0, nLen);
            	nLen = in.read(buf);
            }
            out.close();
            fileOutputSteam.close();
            in.close();
            fileInputStream.close();
            
            fileInputStream = new FileInputStream(strActualPicName);
            in = new BufferedInputStream(fileInputStream);
            fileOutputSteam = new FileOutputStream(strDestPicPath + strPicNameWithExtension);
            out = new BufferedOutputStream(fileOutputSteam);
            
            nLen = in.read(buf);
            while (nLen != -1) {
            	out.write(buf, 0, nLen);
            	nLen = in.read(buf);
            }
            out.close();
            fileOutputSteam.close();
            in.close();
            fileInputStream.close();
            
            System.out.println("对比失败的图片已复制到： " + strDestPicPath);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	public static boolean isRecordsetEqual(Recordset recordset1,
			Recordset recordset2) {
		return isRecordsetEqual(recordset1, recordset2, delta);
	}

	public static boolean isRecordsetEqual(Recordset recordset1, Recordset recordset2, double delta2) {
		FieldInfos fieldInfos1 = recordset1.getFieldInfos();
		FieldInfos fieldInfos2 = recordset2.getFieldInfos();
		int fieldCount1 = 0;
		int fieldCount2 = 0;
		for(int i = 0 ; i < fieldInfos1.getCount(); i++){
			if(!fieldInfos1.get(i).isSystemField()){
				fieldCount1++;
			}
		}
		for(int j = 0 ; j < fieldInfos2.getCount(); j++){
			if(!fieldInfos2.get(j).isSystemField()){
				fieldCount2++;
			}
		}
		if (fieldCount1 != fieldCount2){
			System.out.println(String.format("Compare failed, field count (%s : %s)",fieldCount1,fieldCount2));
			return false;
		}

		String string1 = null;
		String string2 = null;
		int count = recordset1.getFieldCount();
		String fieldNames[] = new String[count];
		for (int i = 0; i < count; i++) {

			string1 = recordset1.getFieldInfos().get(i).getName();
			string2 = recordset2.getFieldInfos().get(i).getName();
			fieldNames[i] = string1;
			if (string1 == null && string2 == null)
				continue;
			//Added by wangdh 2010-08-05
			if (recordset2.getFieldInfos().indexOf(string1) == -1) {
				return false;
			}
			
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount()){
			System.out.println(String.format("Compare failed, record count (%s : %s)",recordset1.getRecordCount(),recordset2.getRecordCount()));
			return false;
		}

		if (recordset1.getRecordCount() == 0)
			return true;

		recordset1.moveFirst();
		recordset2.moveFirst();
		boolean flag = true;
		for (; !recordset1.isEOF();) 
		{
			for (int j = 0; j < count; j++) {
				
				//Added by xuling 2010-08-17
				if(fieldNames[j].toLowerCase().equals("smkey") 
						|| fieldNames[j].equalsIgnoreCase("smsdriw")/*added by zhouqin UDB 四至的精度低于其它引擎*/
						|| fieldNames[j].equalsIgnoreCase("smsdrin")
						|| fieldNames[j].equalsIgnoreCase("smsdrie")
						|| fieldNames[j].equalsIgnoreCase("smsdris")
						|| fieldNames[j].equalsIgnoreCase("SmResistanceA")//ADD BY BOBBY 跨平台时该字段值不同 2011.5
			        	|| fieldNames[j].equalsIgnoreCase("SmResistanceB")
			        	|| fieldNames[j].equalsIgnoreCase("SMGEOMETRYSIZE")//added by shanqc 听zhouhui说这个字段没意义就不比了2011-12-13
			        	|| fieldNames[j].equalsIgnoreCase("SMPPOINT")//added by longzheng 2013-01-21
			        	|| fieldNames[j].equalsIgnoreCase("SMNPOINT")||//added by longzheng 2013-01-21
			        	fieldNames[j].equalsIgnoreCase("SMGEOPOSITION")
				) 
					continue;
				
				Object object1 = recordset1.getFieldValue(j);
				// 徐玲注释，注释原因：sql引擎中的数据集复制前后，
				// 字段的顺序可能会发生变化，所以不用列序号获取列的值，而改为列名
				// Object object2 = recordset2.getFieldValue(j);
				Object object2 = recordset2.getFieldValue(fieldNames[j]);
				if (!isValueEqual(object1, object2, delta2)) {
					System.out.println(String.format("Compare failed, RedcordID(%s : %s), \tSmID(%s : %s),\tCompare field: %s(%s : %s) ",
							recordset1.getID(),recordset2.getID(),recordset1.getFieldValue("SMID"),recordset2.getFieldValue("SMID"),
							fieldNames[j],object1,object2));//string2 -> fieldNames[j] 输出正确对比字段modified by shanqc 2011-12-13
					flag = false;
					//return false;
				}

			}
			recordset1.moveNext();
			recordset2.moveNext();
		}

		return flag;
	}
	
	public static boolean isRecordsetWithoutSMEqual(Recordset recordset1,
			Recordset recordset2, double delta) {
		if (recordset1.getFieldCount() != recordset2.getFieldCount())
			return false;

		String string1 = null;
		String string2 = null;
		int count = recordset1.getFieldCount();
		String fieldNames[] = new String[count];
		for (int i = 0; i < count; i++) {

			string1 = recordset1.getFieldInfos().get(i).getName();
			string2 = recordset2.getFieldInfos().get(i).getName();
			fieldNames[i] = string1;
			if (string1 == null && string2 == null)
				continue;
			//Added by wangdh 2010-08-05
			if (recordset2.getFieldInfos().indexOf(string1) == -1) {
				return false;
			}
			
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount())
			return false;

		if (recordset1.getRecordCount() == 0)
			return true;

		recordset1.moveFirst();
		recordset2.moveFirst();
		boolean flag = true;
		for (; !recordset1.isEOF();) {
			for (int j = 0; j < count; j++) {
				
				//Added by xuling 2010-08-17
				if(fieldNames[j].toLowerCase().startsWith("sm")) 
					continue;
				
				Object object1 = recordset1.getFieldValue(j);
				// 徐玲注释，注释原因：sql引擎中的数据集复制前后，
				// 字段的顺序可能会发生变化，所以不用列序号获取列的值，而改为列名
				// Object object2 = recordset2.getFieldValue(j);
				Object object2 = recordset2.getFieldValue(fieldNames[j]);
				if (!isValueEqual(object1, object2, delta)) {
					System.out.println(fieldNames[j]+":"+object1 + "," + object2);
					flag = false;
					//return false;
				}

			}
			recordset1.moveNext();
			recordset2.moveNext();
		}

		return flag;
	}

	public static boolean isOracleRecordsetIgnoreSYEqual(Recordset recordset1,
			Recordset recordset2){
		
		// 获取记录集的非系统字段数组
		ArrayList<FieldInfo> fArrayList1 = getNSYFieldCount(recordset1);
		ArrayList<FieldInfo> fArrayList2 = getNSYFieldCount(recordset2);
		if (fArrayList1.size() != fArrayList2.size())
			return false;

		// 对比字段信息
		String string1 = null;
		String string2 = null;
		int count = fArrayList1.size();

		for (int i = 0; i < count; i++) {

			string1 = fArrayList1.get(i).getName();
			string2 = fArrayList2.get(i).getName();

			if (string1 == null && string2 == null)
				continue;
			if (string1 == null || string2 == null
					|| !string1.equalsIgnoreCase(string2))
				return false;
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount()){
			System.out.println(String.format("Compare failed, record count (%s : %s)",recordset1.getRecordCount(),recordset2.getRecordCount()));
			return false;
		}
		
		if(recordset1.getRecordCount() == 0)
			return true;
		
		boolean isAllEqual = true;
		
		// 对比记录集中记录值是否正确
		recordset1.moveFirst();
		recordset2.moveFirst();
		
		//Added by xuling 2010.8.18
		//当oracle数据集数据量过大的时候，要一条一条的比较记录集花费时间比较大，
		//所以，如果在一定的时间内，数据集的比较还在进行的话，也就算比较通过
		long starttime = System.currentTimeMillis();
		List<Integer> comparedIds = new ArrayList<Integer>();
		
		while (!recordset1.isEOF()) {
			boolean isRecordEqual = false;

			recordset2.moveFirst();
			while (!recordset2.isEOF()) {
				if(comparedIds.indexOf(recordset2.getID()) != -1){
					recordset2.moveNext();
					continue;
				}
				boolean isFieldEqual = true;
				for (int j = 0; j < count; j++) {
					FieldInfo fieldInfo = fArrayList1.get(j);
					//modified by xuling 2010-09-03  

					Object object1 = recordset1.getFieldValue(fieldInfo.getName());
					Object object2 = recordset2.getFieldValue(fieldInfo.getName());

					if (!isValueEqual(object1, object2, delta)) {
						System.out.println(String.format("Compare failed, RedcordID(%s : %s),\tSmID(%s : %s),\tCompare field: %s(%s : %s) ",
								recordset1.getID(),recordset2.getID(),recordset1.getFieldValue("SMID"),recordset2.getFieldValue("SMID"),
								string2,object1,object2));
						isFieldEqual = false;
						break;
					}
					
				}
				if (isFieldEqual) {
					isRecordEqual = true;
					comparedIds.add(recordset2.getID());
					break;
				}
				
				recordset2.moveNext();
			}
			if (isRecordEqual == false) {
				isAllEqual = false;
				break;
			}
			
			recordset1.moveNext();

			//超时3分钟，比较退出
			if((System.currentTimeMillis()-starttime)/1000>=180)
				return isAllEqual;
		}
		return isAllEqual;
			
	}
	/**
	 * 对比两个记录集不包含系统字段
	 * 
	 * @param recordset1
	 * @param recordset2
	 * @author wangdh
	 */
	public static boolean isRecordsetIgnoreSYEqual(Recordset recordset1,
			Recordset recordset2) {
		// 获取记录集的非系统字段数组
		ArrayList<FieldInfo> fArrayList1 = getNSYFieldCount(recordset1);
		ArrayList<FieldInfo> fArrayList2 = getNSYFieldCount(recordset2);
		if (fArrayList1.size() != fArrayList2.size())
			return false;

		// 对比字段信息
		String string1 = null;
		String string2 = null;
		int count = fArrayList1.size();

		for (int i = 0; i < count; i++) {

			string1 = fArrayList1.get(i).getName();
			string2 = fArrayList2.get(i).getName();

			if (string1 == null && string2 == null)
				continue;
			if (string1 == null || string2 == null
					|| !string1.equalsIgnoreCase(string2))
				return false;
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount())
			return false;

		if (recordset1.getRecordCount() == 0)
			return true;

		// 对比记录集中记录值是否正确
		recordset1.moveFirst();
		recordset2.moveFirst();

		for (; !recordset1.isEOF();) {
			for (int j = 0; j < count; j++) {
				FieldInfo fieldInfo = fArrayList1.get(j);
				Object object1 = recordset1.getFieldValue(fieldInfo.getName());
				Object object2 = recordset2.getFieldValue(fieldInfo.getName());
				if (!isValueEqual(object1, object2, delta)) {
					System.out.println(object1);
					System.out.println(object2);
					return false;
				}

			}
			recordset1.moveNext();
			recordset2.moveNext();
		}

		return true;
	}

	/**
	 * 获取记录集非系统字段集合
	 * 
	 * @param recordset1
	 * @author wangdh
	 */
	private static ArrayList<FieldInfo> getNSYFieldCount(Recordset recordset1) {
		ArrayList<FieldInfo> fArrayList = new ArrayList<FieldInfo>();
		for (int i = 0; i < recordset1.getFieldCount(); i++) {
			FieldInfo fieldInfo = recordset1.getFieldInfos().get(i);
			if (!fieldInfo.isSystemField()) {
				fArrayList.add(fieldInfo);
			}
		}
		return fArrayList;
	}

	/**
	 * 对比两个字符串数组
	 * 
	 * @param names1
	 * @param names2
	 * @return
	 */
	public static boolean isStringsEquals(String[] names1, String[] names2) {
		if (names1 == null && names2 == null) {
			return true;
		}
		if (names1 == null || names2 == null) {
			return false;
		}
		if (names1.length != names2.length) {
			return false;
		}
		Arrays.sort(names1);
		Arrays.sort(names2);
		for (int i = 0; i < names1.length; i++) {
			if (!names1[i].equals(names2[i])) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 对比两个double数组
	 * 
	 * @param values1
	 * @param values2
	 * @return
	 */
	public static boolean isDoubleEquals(double[] values1, double[] values2) {
		if (values1 == null && values2 == null) {
			return true;
		}
		if (values1 == null || values2 == null) {
			return false;
		}
		if (values1.length != values2.length) {
			return false;
		}
		Arrays.sort(values1);
		Arrays.sort(values2);
		for (int i = 0; i < values1.length; i++) {
			if (Math.abs(values1[i] - values2[i]) > delta)
				return false;
		}
		return true;
	}

	// /////////
	// ////////////////////////////////////////////////////////////////////////////////////
	// 对于Oracle数据源，由于smid排序混乱，需要特殊处理。为节省比较时间，可以只比较记录集个数、字段个数和名称，不涉及各个
	// 字段值的比较 。本方法实现了所有记录逐个对比，如果在第二个记录集中有，则成功。 -----Added by Hutq, 2010-6-2
	public static boolean isOracleRecordsetEqual(Recordset recordset1,
			Recordset recordset2) {
		return isOracleRecordsetEqual(recordset1, recordset2, delta);
	}

	public static boolean isOracleRecordsetEqual(Recordset recordset1,
			Recordset recordset2, double delta2) {
		FieldInfos fieldInfos1 = recordset1.getFieldInfos();
		FieldInfos fieldInfos2 = recordset2.getFieldInfos();
		int fieldCount1 = 0;
		int fieldCount2 = 0;
		for(int i = 0 ; i < fieldInfos1.getCount(); i++){
			if(!fieldInfos1.get(i).isSystemField()){
				fieldCount1++;
			}
		}
		for(int j = 0 ; j < fieldInfos2.getCount(); j++){
			if(!fieldInfos2.get(j).isSystemField()){
				fieldCount2++;
			}
		}
		if (fieldCount1 != fieldCount2){
			System.out.println(String.format("Compare failed, field count (%s : %s)",fieldCount1,fieldCount2));
			return false;
		}
		
		String string1 = null;
		String string2 = null;
		int count = recordset1.getFieldCount();

		for (int i = 0; i < count; i++) {

			string1 = recordset1.getFieldInfos().get(i).getName();
			//string2 = recordset2.getFieldInfos().get(i).getName();

			if (string1 == null && string2 == null)
				continue;

			//if (string1 == null || string2 == null || !string1.equals(string2))
			//	return false;
			//Added by xuling 2010-08-06 复制后，字段的列的位置可能会变化
			if (recordset2.getFieldInfos().indexOf(string1) == -1) {
				return false;
			}
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount()){
			System.out.println(String.format("Compare failed, record count (%s : %s)",recordset1.getRecordCount(),recordset2.getRecordCount()));
			return false;
		}
		
		boolean isAllEqual = true;

		recordset1.moveFirst();
		recordset2.moveFirst();

		//Added by xuling 2010.8.18
		//当oracle数据集数据量过大的时候，要一条一条的比较记录集花费时间比较大，
		//所以，如果在一定的时间内，数据集的比较还在进行的话，也就算比较通过
		long starttime = System.currentTimeMillis();
		List<Integer> comparedIds = new ArrayList<Integer>();
		
		while (!recordset1.isEOF()) {
			
			boolean isRecordEqual = false;

			recordset2.moveFirst();	
			
			while (!recordset2.isEOF()) {
				
				if(comparedIds.indexOf(recordset2.getID()) != -1){
					recordset2.moveNext();
					continue;
				}
				
				boolean isFieldEqual = true;
				for (int j = 0; j < count; j++) {
					string2= recordset2.getFieldInfos().get(j).getName();
					//modified by xuling 2010-08-18  
					if(string2.equalsIgnoreCase("smid")
							|| string2.equalsIgnoreCase("smkey")
							|| string2.equalsIgnoreCase("smGeometry")
							|| string2.equalsIgnoreCase("SMRESISTANCEA")//ADD BY BOBBY 跨平台时该字段值不同 2011.5
							|| string2.equalsIgnoreCase("SMRESISTANCEB")
							|| string2.equalsIgnoreCase("smsdriw")
							|| string2.equalsIgnoreCase("smsdrin")
							|| string2.equalsIgnoreCase("smsdrie")
							|| string2.equalsIgnoreCase("smsdris")
							|| string2.equalsIgnoreCase("SmGranule")//added by shanqc 2011-12-22
							|| string2.equalsIgnoreCase("Smppoint")//added by longzheng 2013-01-21
							|| string2.equalsIgnoreCase("Smnpoint")//added by longzheng 2013-01-21
							|| string2.equalsIgnoreCase("SmGeoPosition")
					)
					 {
						continue;
						
					 }
					Object object1 = recordset1.getFieldValue(string2);
					Object object2 = recordset2.getFieldValue(string2);
					if (!isValueEqual(object1, object2, delta2)) {
						//目前这种比法，输出来没什么价值，在后面输出
//						System.out.println(String.format("Compare failed, RedcordID(%s : %s),\tSmID(%s : %s),\tCompare field: %s(%s : %s) ",
//								recordset1.getID(),recordset2.getID(),recordset1.getFieldValue("SMID"),recordset2.getFieldValue("SMID"),
//								string2,object1,object2));
						isFieldEqual = false;
						break;
					}
				}
				if (isFieldEqual) {
					isRecordEqual = true;
					comparedIds.add(recordset2.getID());
					break;
				}
				recordset2.moveNext();
			}
			
			
			if (isRecordEqual == false) {
				isAllEqual = false;
				System.out.println(String.format("Compare failed, RedcordID %s,\tSmID %s,",
						recordset1.getID(),recordset1.getFieldValue("SMID")));
				break;
			}
			
			//超时3分钟，比较退出
			if((System.currentTimeMillis()-starttime)/1000>=180)
				return isAllEqual;
			
			recordset1.moveNext();
		}
		return isAllEqual;

		//以下算法执行效率太低，暂时屏蔽掉。---Hutq，2010年8月12日
//		boolean isAllEqual = true;
//
//		recordset1.moveFirst();
//		recordset2.moveFirst();
//
//		while (!recordset1.isEOF()) {
//			boolean isRecordEqual = false;
//
//			recordset2.moveFirst();
//			while (!recordset2.isEOF()) {
//				boolean isFieldEqual = true;
//				for (int j = 0; j < count; j++) {
//					string2= recordset2.getFieldInfos().get(j).getName();
//					//modified by xulinh 2010-08-06  以sm开头的字段是系统字段，可以不用比较
//					if(string2.toLowerCase().startsWith("sm"))//.equalsIgnoreCase("SmID"))
//					 {
//						continue;
//					 }
//
//					Object object1 = recordset1.getFieldValue(j);
//					Object object2 = recordset2.getFieldValue(j);
//
//					if (!isValueEqual(object1, object2, delta)) {
//						isFieldEqual = false;
//						break;
//					}
//				}
//				if (isFieldEqual) {
//					isRecordEqual = true;
//					break;
//				}
//				recordset2.moveNext();
//			}
//			if (isRecordEqual == false) {
//				isAllEqual = false;
//				// if(!recordset2.isEOF())
//				// {
//				// for (int j = 0; j < count; j++) {
//				// Object object1 = recordset1.getFieldValue(j);
//				// Object object2 = recordset2.getFieldValue(j);
//				// System.out.println(object1.toString() + "---" +
//				// object2.toString());
//				// }
//				// }
//				break;
//			}
//			recordset1.moveNext();
//		}
//		return isAllEqual;

	}
	
	public static boolean isOracleRecordsetWithoutSMEqual(Recordset recordset1,
			Recordset recordset2, double delta) {
		if (recordset1.getFieldCount() != recordset2.getFieldCount())
			return false;

		String string1 = null;
		String string2 = null;
		int count = recordset1.getFieldCount();

		for (int i = 0; i < count; i++) {

			string1 = recordset1.getFieldInfos().get(i).getName();
			//string2 = recordset2.getFieldInfos().get(i).getName();

			if (string1 == null && string2 == null)
				continue;

			//if (string1 == null || string2 == null || !string1.equals(string2))
			//	return false;
			//Added by xuling 2010-08-06 复制后，字段的列的位置可能会变化
			if (recordset2.getFieldInfos().indexOf(string1) == -1) {
				return false;
			}
		}

		if (recordset1.getRecordCount() != recordset2.getRecordCount())
			return false;
		
		boolean isAllEqual = true;

		recordset1.moveFirst();
		recordset2.moveFirst();

		//Added by xuling 2010.8.18
		//当oracle数据集数据量过大的时候，要一条一条的比较记录集花费时间比较大，
		//所以，如果在一定的时间内，数据集的比较还在进行的话，也就算比较通过
		long starttime = System.currentTimeMillis();
		
		while (!recordset1.isEOF()) {
			boolean isRecordEqual = false;

			recordset2.moveFirst();
			while (!recordset2.isEOF()) {
				boolean isFieldEqual = true;
				for (int j = 0; j < count; j++) {
					string2= recordset2.getFieldInfos().get(j).getName();
					//modified by xuling 2010-08-18  
					if(string2.toLowerCase().startsWith("sm"))
					 {
						continue;
					 }

					Object object1 = recordset1.getFieldValue(string2);
					Object object2 = recordset2.getFieldValue(string2);

					if (!isValueEqual(object1, object2, delta)) {
						
						isFieldEqual = false;
						break;
					}
				}
				if (isFieldEqual) {
					isRecordEqual = true;
					break;
				}
				recordset2.moveNext();
			}
			if (isRecordEqual == false) {
				isAllEqual = false;
				break;
			}
			
			//超时3分钟，比较退出
			if((System.currentTimeMillis()-starttime)/1000>=180)
				return isAllEqual;
			
			recordset1.moveNext();
		}
		return isAllEqual;

		//以下算法执行效率太低，暂时屏蔽掉。---Hutq，2010年8月12日
//		boolean isAllEqual = true;
//
//		recordset1.moveFirst();
//		recordset2.moveFirst();
//
//		while (!recordset1.isEOF()) {
//			boolean isRecordEqual = false;
//
//			recordset2.moveFirst();
//			while (!recordset2.isEOF()) {
//				boolean isFieldEqual = true;
//				for (int j = 0; j < count; j++) {
//					string2= recordset2.getFieldInfos().get(j).getName();
//					//modified by xulinh 2010-08-06  以sm开头的字段是系统字段，可以不用比较
//					if(string2.toLowerCase().startsWith("sm"))//.equalsIgnoreCase("SmID"))
//					 {
//						continue;
//					 }
//
//					Object object1 = recordset1.getFieldValue(j);
//					Object object2 = recordset2.getFieldValue(j);
//
//					if (!isValueEqual(object1, object2, delta)) {
//						isFieldEqual = false;
//						break;
//					}
//				}
//				if (isFieldEqual) {
//					isRecordEqual = true;
//					break;
//				}
//				recordset2.moveNext();
//			}
//			if (isRecordEqual == false) {
//				isAllEqual = false;
//				// if(!recordset2.isEOF())
//				// {
//				// for (int j = 0; j < count; j++) {
//				// Object object1 = recordset1.getFieldValue(j);
//				// Object object2 = recordset2.getFieldValue(j);
//				// System.out.println(object1.toString() + "---" +
//				// object2.toString());
//				// }
//				// }
//				break;
//			}
//			recordset1.moveNext();
//		}
//		return isAllEqual;

	}

	// /////////
	// ////////////////////////////////////////////////////////////////////////////////////

	public static boolean isDatasetVectorEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2) {
		if (datasetVector1 == datasetVector2)
			return true;
		return isDatasetVectorEqual(datasetVector1, datasetVector2, delta);
	}
	
	// 增加一个排序字段的参数
	public static boolean isDatasetVectorEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2, String sortField) {
		if (datasetVector1 == datasetVector2)
			return true;
		return isDatasetVectorEqual(datasetVector1, datasetVector2, delta,sortField);
	}
	
	public static boolean isDatasetVectorWhitoutSMEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2) {
		if (datasetVector1 == datasetVector2)
			return true;
		return isDatasetVectorWithoutSMEqual(datasetVector1, datasetVector2, delta);
	}

	public static boolean isDatasetVectorEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2, double delta2) {
        FieldInfos fieldInfos = datasetVector1.getFieldInfos();
        String strFieldName = fieldInfos.getFieldNameBySign(FieldSign.ID);
	    return isDatasetVectorEqual(datasetVector1,datasetVector2, delta2, strFieldName);
	}
	
	//songlan:增加按照某个字段排序的对比结果数据函数。
	public static boolean isDatasetVectorEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2, double delta2, String sortField) {
		
		boolean b = false;
		Recordset recordset1 = null;
		Recordset recordset2 = null;
		try {
			System.out.println(String.format("Compare start, %s : %s , sort field: %s", datasetVector1.getName(),datasetVector2.getName(),sortField));
			QueryParameter parameter = new QueryParameter();
			parameter.setAttributeFilter("");
			parameter.setCursorType(CursorType.STATIC);
			parameter.setOrderBy(new String[] { sortField+" asc" });
			recordset1 = datasetVector1.query(parameter);
			recordset2 = datasetVector2.query(parameter);

			// Added by Hutq, 2010-6-2
			// 判断是否为Oracle引擎
			EngineType type1 = recordset1.getDataset().getDatasource()
					.getEngineType();
			EngineType type2 = recordset2.getDataset().getDatasource()
					.getEngineType();
			//DB2引擎也这样比较一下 added by xuling 2011.4.6
			if ((type1 == EngineType.ORACLEPLUS
					&& type2 == EngineType.ORACLEPLUS)
					|| (type1 == EngineType.DB2
					&& type2 == EngineType.DB2)
					||(type1 == EngineType.DM
					&&type2 == EngineType.DM)||
					(type1 == EngineType.ORACLESPATIAL
					&& type2 == EngineType.ORACLESPATIAL)) 
			{
				b = isOracleRecordsetEqual(recordset1, recordset2, delta2);
			} else {
				b = isRecordsetEqual(recordset1, recordset2, delta2);
			}
		} catch (Exception e) {
		} finally {
			if (recordset1 != null)
				recordset1.dispose();
			if (recordset2 != null)
				recordset2.dispose();
		}
		return b;
	}
	
	public static boolean isDatasetVectorWithoutSMEqual(DatasetVector datasetVector1,
			DatasetVector datasetVector2, double delta) {
		
		boolean b = false;
		Recordset recordset1 = null;
		Recordset recordset2 = null;
		try {
			System.out.println(String.format("Compare start, %s : %s ", datasetVector1.getName(),datasetVector2.getName()));
			QueryParameter parameter = new QueryParameter();
			parameter.setAttributeFilter("");
			parameter.setCursorType(CursorType.STATIC);
			parameter.setOrderBy(new String[] { "smid asc" });
			recordset1 = datasetVector1.query(parameter);
			recordset2 = datasetVector2.query(parameter);

			// Added by Hutq, 2010-6-2
			// 判断是否为Oracle引擎
			EngineType type1 = recordset1.getDataset().getDatasource()
					.getEngineType();
			EngineType type2 = recordset2.getDataset().getDatasource()
					.getEngineType();
			if ((type1 == EngineType.ORACLEPLUS)
					&& (type2 == EngineType.ORACLEPLUS)) {
				b = isOracleRecordsetWithoutSMEqual(recordset1, recordset2, delta);
			} else {
				b = isRecordsetWithoutSMEqual(recordset1, recordset2, delta);
			}
		} catch (Exception e) {
		} finally {
			if (recordset1 != null)
				recordset1.dispose();
			if (recordset2 != null)
				recordset2.dispose();
		}
		return b;

	}

	public static boolean isDatasetVectorIgnoreSystemFieldsEqual(
			DatasetVector datasetVector1, DatasetVector datasetVector2) {

		boolean b = false;
		Recordset recordset1 = null;
		Recordset recordset2 = null;
		try {
			System.out.println(String.format("Compare start, ignore system field, %s : %s ", datasetVector1.getName(),datasetVector2.getName()));
			QueryParameter parameter = new QueryParameter();
			parameter.setAttributeFilter("");
			parameter.setCursorType(CursorType.STATIC);
			parameter.setOrderBy(new String[] { "smid asc" });
			recordset1 = datasetVector1.query(parameter);
			recordset2 = datasetVector2.query(parameter);
			
			// 判断是否为Oracle引擎
			EngineType type1 = recordset1.getDataset().getDatasource()
					.getEngineType();
			EngineType type2 = recordset2.getDataset().getDatasource()
					.getEngineType();
			
			//oracle引擎乱序了，特殊处理 added by xuling 2010.8.17
			if (type1 == EngineType.ORACLEPLUS || type1 == EngineType.ORACLESPATIAL ) {
				b = isOracleRecordsetIgnoreSYEqual(recordset1, recordset2);
			} else {
				b = isRecordsetIgnoreSYEqual(recordset1, recordset2);
			}
		
		} catch (Exception e) {
		} finally {
			if (recordset1 != null)
				recordset1.dispose();
			if (recordset2 != null)
				recordset2.dispose();
		}
		return b;

	}

	public static boolean isDatasetGridEqual(DatasetGrid datasetGrid1,
			DatasetGrid datasetGrid2) {
		if (datasetGrid1 == datasetGrid2) {
			return true;
		}
		return isDatasetGridEqual(datasetGrid1, datasetGrid2, delta);
	}

	public static boolean isDatasetGridEqual(DatasetGrid datasetGrid1,
			DatasetGrid datasetGrid2, double delta2) {

		if (datasetGrid1.getWidth() != datasetGrid2.getWidth())
			return false;
		if (datasetGrid1.getHeight() != datasetGrid2.getHeight())
			return false;

		int width = datasetGrid1.getWidth();
		int height = datasetGrid1.getHeight();

		int errorCount=0;
		
		for (int i = 0; i < width; i += 2) {
			for (int j = 0; j < height; j += 2) {
				double d1 = datasetGrid1.getValue(i, j);
				double d2 = datasetGrid2.getValue(i, j);
				if (Math.abs(d1 - d2) > delta2)
					errorCount++;
			}
		}
		//如果相同值的点大于百分之99则任务对比通过
		if((double)(errorCount)/(double)(width*height/4)>=0.01)
		{
		    return false;
		}
		return true;
	}

	public static boolean isDatasetImageEqual(DatasetImage datasetImage1,
			DatasetImage datasetImage2) {
		return isDatasetImageEqual(datasetImage1, datasetImage2, delta);
	}

	public static boolean isDatasetImageEqual(DatasetImage datasetImage1,
			DatasetImage datasetImage2, double delta) {
		if (datasetImage1 == null && datasetImage2 == null) {
			return true;
		}
		if (datasetImage1 == null || datasetImage2 == null) {
			return false;
		}
		if (datasetImage1.getWidth() != datasetImage2.getWidth())
			return false;
		if (datasetImage1.getHeight() != datasetImage2.getHeight())
			return false;

		int width = datasetImage1.getWidth();
		int height = datasetImage2.getHeight();

		int count=0;
		double p=0;
		if(datasetImage1.getBandCount()!=datasetImage2.getBandCount()){
			return false;
		}
		for(int index = 0;index<datasetImage1.getBandCount();index++){
			for (int i = 0; i < width; i++) {
				for (int j = 0; j < height; j++) {
					double d1 = datasetImage1.getValue(i, j ,index);
					double d2 = datasetImage2.getValue(i, j ,index);
					if (Math.abs(d1-d2) > delta)
					{
						//System.out.println("width"+i+"and"+"height"+j);
						//count=count+1;
						return false;
					}
				}
			}
		}
		
		//p=(double)count/(width*height);
		//System.out.println("p="+p);

		return true;
	}

	public static boolean isGeoEllipsoidEqual(GeoEllipsoid geoEllipsoid1,
			GeoEllipsoid geoEllipsoid2) {
		return isGeoEllipsoidEqual(geoEllipsoid1, geoEllipsoid2, delta);
	}

	public static boolean isGeoEllipsoidEqual(GeoEllipsoid geoEllipsoid1,
			GeoEllipsoid geoEllipsoid2, double delta) {
		if (!geoEllipsoid1.getPosition().equals(geoEllipsoid2.getPosition())
				|| Math.abs(geoEllipsoid1.getSemiAxisX()
						- geoEllipsoid2.getSemiAxisX()) > delta
				|| Math.abs(geoEllipsoid1.getSemiAxisY()
						- geoEllipsoid2.getSemiAxisY()) > delta
				|| Math.abs(geoEllipsoid1.getSemiAxisZ()
						- geoEllipsoid2.getSemiAxisZ()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoPie3DEqual(GeoPie3D geoPie3D1, GeoPie3D geoPie3D2) {
		return isGeoPie3DEqual(geoPie3D1, geoPie3D2, delta);
	}

	public static boolean isGeoPie3DEqual(GeoPie3D geoPie3D1,
			GeoPie3D geoPie3D2, double delta) {
		if (!geoPie3D1.getPosition().equals(geoPie3D2.getPosition())
				|| Math.abs(geoPie3D1.getSemimajorAxis()
						- geoPie3D2.getSemimajorAxis()) > delta
				|| Math.abs(geoPie3D1.getSemiminorAxis()
						- geoPie3D2.getSemiminorAxis()) > delta
				|| Math.abs(geoPie3D1.getStartAngle()
						- geoPie3D2.getStartAngle()) > delta
				|| Math.abs(geoPie3D1.getSweepAngle()
						- geoPie3D2.getSweepAngle()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoPieCylinderEqual(GeoPieCylinder geoPieCylinder1,
			GeoPieCylinder geoPieCylinder2) {
		return isGeoPieCylinderEqual(geoPieCylinder1, geoPieCylinder2, delta);
	}

	public static boolean isGeoPieCylinderEqual(GeoPieCylinder geoPieCylinder1,
			GeoPieCylinder geoPieCylinder2, double delta) {
		if (!geoPieCylinder1.getPosition()
				.equals(geoPieCylinder2.getPosition())
				|| Math.abs(geoPieCylinder1.getSemimajorAxis()
						- geoPieCylinder2.getSemimajorAxis()) > delta
				|| Math.abs(geoPieCylinder1.getSemiminorAxis()
						- geoPieCylinder2.getSemiminorAxis()) > delta
				|| Math.abs(geoPieCylinder1.getStartAngle()
						- geoPieCylinder2.getStartAngle()) > delta
				|| Math.abs(geoPieCylinder1.getSweepAngle()
						- geoPieCylinder2.getSweepAngle()) > delta
				|| Math.abs(geoPieCylinder1.getHeight()
						- geoPieCylinder2.getHeight()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoCylinderEqual(GeoCylinder geoCylinder1,
			GeoCylinder geoCylinder2) {
		return isGeoCylinderEqual(geoCylinder1, geoCylinder2, delta);
	}

	public static boolean isGeoCylinderEqual(GeoCylinder geoCylinder1,
			GeoCylinder geoCylinder2, double delta) {
		if (!geoCylinder1.getPosition().equals(geoCylinder2.getPosition())
				|| Math.abs(geoCylinder1.getTopRadius()
						- geoCylinder2.getTopRadius()) > delta
				|| Math.abs(geoCylinder1.getBottomRadius()
						- geoCylinder2.getBottomRadius()) > delta
				|| Math
						.abs(geoCylinder1.getHeight()
								- geoCylinder2.getHeight()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoConeEqual(GeoCone geoCone1, GeoCone geoCone2) {
		return isGeoConeEqual(geoCone1, geoCone2, delta);
	}

	public static boolean isGeoConeEqual(GeoCone geoCone1, GeoCone geoCone2,
			double delta) {
		if (!geoCone1.getPosition().equals(geoCone2.getPosition())
				|| Math.abs(geoCone1.getBottomRadius()
						- geoCone2.getBottomRadius()) > delta
				|| Math.abs(geoCone1.getHeight() - geoCone2.getHeight()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoHemiSphereEqual(GeoHemiSphere geoHemiSphere1,
			GeoHemiSphere geoHemiSphere2) {
		return isGeoHemiSphereEqual(geoHemiSphere1, geoHemiSphere2, delta);
	}

	public static boolean isGeoHemiSphereEqual(GeoHemiSphere geoHemiSphere1,
			GeoHemiSphere geoHemiSphere2, double delta) {
		if (!geoHemiSphere1.getPosition().equals(geoHemiSphere2.getPosition())
				|| Math.abs(geoHemiSphere1.getRadius()
						- geoHemiSphere2.getRadius()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoCircle3DEqual(GeoCircle3D geoCircle3D1,
			GeoCircle3D geoCircle3D2) {
		return isGeoCircle3DEqual(geoCircle3D1, geoCircle3D2, delta);
	}

	public static boolean isGeoCircle3DEqual(GeoCircle3D geoCircle3D1,
			GeoCircle3D geoCircle3D2, double delta) {
		if (!geoCircle3D1.getPosition().equals(geoCircle3D2.getPosition())
				|| Math
						.abs(geoCircle3D1.getRadius()
								- geoCircle3D2.getRadius()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoSphereEqual(GeoSphere geoSphere1,
			GeoSphere geoSphere2) {
		return isGeoSphereEqual(geoSphere1, geoSphere2, delta);
	}

	public static boolean isGeoSphereEqual(GeoSphere geoSphere1,
			GeoSphere geoSphere2, double delta) {
		if (!geoSphere1.getPosition().equals(geoSphere2.getPosition())
				|| Math.abs(geoSphere1.getRadius() - geoSphere2.getRadius()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoBoxEqual(GeoBox geoBox1, GeoBox geoBox2) {
		return isGeoBoxEqual(geoBox1, geoBox2, delta);
	}

	public static boolean isGeoBoxEqual(GeoBox geoBox1, GeoBox geoBox2,
			double delta) {
		if (!geoBox1.getCenter().equals(geoBox2.getCenter())
				|| !geoBox1.getBottomSize().equals(geoBox2.getBottomSize())
				|| Math.abs(geoBox1.getHeight() - geoBox2.getHeight()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoPyramidEqual(GeoPyramid geoPyramid1,
			GeoPyramid geoPyramid2) {
		return isGeoPyramidEqual(geoPyramid1, geoPyramid2, delta);
	}

	public static boolean isGeoPyramidEqual(GeoPyramid geoPyramid1,
			GeoPyramid geoPyramid2, double delta) {
		if (!geoPyramid1.getPosition().equals(geoPyramid2.getPosition())
				|| !geoPyramid1.getBottomSize().equals(
						geoPyramid2.getBottomSize())
				|| Math.abs(geoPyramid1.getHeight() - geoPyramid2.getHeight()) > delta)
			return false;
		return true;
	}

	// 组件中有Rectangle2D的equals方法，此处只处理容限
	public static boolean isRectangle2DEqual(Rectangle2D rectangle2D1,
			Rectangle2D rectangle2D2, double delta) {
		if (Math.abs(rectangle2D1.getTop() - rectangle2D2.getTop()) < delta
				&& Math
						.abs(rectangle2D1.getBottom()
								- rectangle2D2.getBottom()) < delta
				&& Math.abs(rectangle2D1.getWidth() - rectangle2D2.getWidth()) < delta
				&& Math
						.abs(rectangle2D1.getHeight()
								- rectangle2D2.getHeight()) < delta)
			return true;
		return false;
	}

	public static boolean isPoint2DsEqual(Point2Ds point2Ds1, Point2Ds point2Ds2) {
		return isPoint2DsEqual(point2Ds1, point2Ds2, delta);
	}

	public static boolean isPoint2DsEqual(Point2Ds point2Ds1,
			Point2Ds point2Ds2, double delta) {
		if (point2Ds1.getCount() != point2Ds2.getCount())
			return false;

		int count = point2Ds1.getCount();
		for (int i = 0; i < count; i++) {
			if (Math.abs(point2Ds1.getItem(i).getX()
					- point2Ds2.getItem(i).getX()) > delta
					|| Math.abs(point2Ds1.getItem(i).getY()
							- point2Ds2.getItem(i).getY()) > delta) {
				return false;
			}
		}
		return true;
	}

	public static boolean isPoint3DsEqual(Point3Ds point3Ds1, Point3Ds point3Ds2) {
		return isPoint3DsEqual(point3Ds1, point3Ds2, delta);
	}

	public static boolean isPoint3DsEqual(Point3Ds point3Ds1,
			Point3Ds point3Ds2, double delta) {
		if (point3Ds1.getCount() != point3Ds2.getCount())
			return false;
		int count = point3Ds1.getCount();
		for (int i = 0; i < count; i++) {
			if (Math.abs(point3Ds1.getItem(i).getX()
					- point3Ds2.getItem(i).getX()) > delta
					|| Math.abs(point3Ds1.getItem(i).getY()
							- point3Ds2.getItem(i).getY()) > delta
					|| Math.abs(point3Ds1.getItem(i).getZ()
							- point3Ds2.getItem(i).getZ()) > delta)
				return false;
		}
		return true;
	}

	public static boolean isPoint2DsReverseEqual(Point2Ds point2Ds1,
			Point2Ds point2Ds2) {
		return isPoint2DsReverseEqual(point2Ds1, point2Ds2, delta);
	}

	public static boolean isPoint2DsReverseEqual(Point2Ds point2Ds1,
			Point2Ds point2Ds2, double delta) {
		if (point2Ds1.getCount() != point2Ds2.getCount())
			return false;
		int count = point2Ds1.getCount();
		for (int i = 0; i < count; i++) {
			if (Math.abs(point2Ds1.getItem(i).getX()
					- point2Ds2.getItem(count - i - 1).getX()) > delta
					|| Math.abs(point2Ds1.getItem(i).getY()
							- point2Ds2.getItem(count - i - 1).getY()) > delta)
				return false;
		}
		return true;
	}

	public static boolean isPointMsEqual(PointMs pointMs1, PointMs pointMs2) {
		return isPointMsEqual(pointMs1, pointMs2, delta);
	}

	public static boolean isPointMsEqual(PointMs pointMs1, PointMs pointMs2,
			double delta) {
		if (pointMs1.getCount() != pointMs2.getCount())
			return false;
		int count = pointMs1.getCount();
		for (int i = 0; i < count; i++) {
			if (Math.abs(pointMs1.getItem(i).getX()
					- pointMs2.getItem(i).getX()) > delta
					|| Math.abs(pointMs1.getItem(i).getY()
							- pointMs2.getItem(i).getY()) > delta
					|| Math.abs(pointMs1.getItem(i).getM()
							- pointMs2.getItem(i).getM()) > delta)
				return false;
		}
		return true;
	}

	public static boolean isTextPartEqual(TextPart textPart1, TextPart textPart2) {
		return isTextPartEqual(textPart1, textPart2, delta);
	}

	public static boolean isTextPartEqual(TextPart textPart1,
			TextPart textPart2, double delta) {
		if (Math.abs(textPart1.getX() - textPart2.getX()) > delta
				|| Math.abs(textPart1.getY() - textPart2.getY()) > delta
				|| Math.abs(textPart1.getRotation() - textPart2.getRotation()) > delta
				|| !textPart1.getText().equals(textPart2.getText()))
			return false;
		else
			return true;
	}

	public static boolean isTextPart3DEqual(TextPart3D textPart3D1,
			TextPart3D textPart3D2) {
		return isTextPart3DEqual(textPart3D1, textPart3D2, delta);
	}

	public static boolean isTextPart3DEqual(TextPart3D textPart3D1,
			TextPart3D textPart3D2, double delta) {
		if (Math.abs(textPart3D1.getX() - textPart3D2.getX()) > delta
				|| Math.abs(textPart3D1.getY() - textPart3D2.getY()) > delta
				|| Math.abs(textPart3D1.getZ() - textPart3D2.getZ()) > delta
				|| !textPart3D1.getText().equals(textPart3D2.getText()))
			return false;
		else
			return true;
	}

	public static boolean isTextStyleEqual(TextStyle textStyle1,
			TextStyle textStyle2) {
		return isTextStyleEqual(textStyle1, textStyle2, delta);
	}

	public static boolean isTextStyleEqual(TextStyle textStyle1,
			TextStyle textStyle2, double delta) {

		if (textStyle1.isSizeFixed() ^ textStyle2.isSizeFixed())
			return false;

		try {
			Class cls = Class.forName("com.supermap.data.TextStyle");
			Method[] methods = cls.getDeclaredMethods();
			for (Method method : methods) {
				if (method.getName().startsWith("get")) {
					Object object1 = method.invoke(textStyle1, new Object[] {});
					Object object2 = method.invoke(textStyle2, new Object[] {});
					boolean b = isValueEqual(object1, object2, delta);
					if (!b)
						return false;
				}
			}

		} catch (Exception e) {
		}

		return true;
	}

	// GeoCompound的比较待议
	public static boolean isGeoCompoundEqual(GeoCompound geoCompound1,
			GeoCompound geoCompound2) {
		if (geoCompound1.getPartCount() != geoCompound2.getPartCount())
			return false;
		int count = geoCompound1.getPartCount();
		for (int i = 0; i < count; i++) {
			Geometry geometry1 = geoCompound1.getPart(i);
			Geometry geometry2 = geoCompound2.getPart(i);
			Class cls1 = geometry1.getClass();
			Class cls2 = geometry2.getClass();
			if (cls1 != cls2) {
				return false;
			}
			// if (!geoCompound1.toXML().equals(geoCompound2.toXML()))
			// return false;
		}
		return true;
	}

	public static boolean isGeoPointEqual(GeoPoint geoPoint1, GeoPoint geoPoint2) {
		return isGeoPointEqual(geoPoint1, geoPoint2, delta);
	}

	public static boolean isGeoPointEqual(GeoPoint geoPoint1,
			GeoPoint geoPoint2, double delta) {
		if (Math.abs(geoPoint1.getX() - geoPoint2.getX()) > delta
				|| Math.abs(geoPoint1.getY() - geoPoint2.getY()) > delta)
			return false;
		else
			return true;
	}

	public static boolean isGeoPoint3DEqual(GeoPoint3D geoPoint3D1,
			GeoPoint3D geoPoint3D2) {
		return isGeoPoint3DEqual(geoPoint3D1, geoPoint3D2, delta);
	}

	public static boolean isGeoPoint3DEqual(GeoPoint3D geoPoint3D1,
			GeoPoint3D geoPoint3D2, double delta) {
		if (Math.abs(geoPoint3D1.getX() - geoPoint3D2.getX()) > delta
				|| Math.abs(geoPoint3D1.getY() - geoPoint3D2.getY()) > delta
				|| Math.abs(geoPoint3D1.getZ() - geoPoint3D2.getZ()) > delta)
			return false;
		else
			return true;
	}

	public static boolean isGeoLineEqual(GeoLine geoLine1, GeoLine geoLine2) {
		return isGeoLineEqual(geoLine1, geoLine2, delta);
	}

	public static boolean isGeoLineEqual(GeoLine geoLine1, GeoLine geoLine2,
			double delta) {
		if (Math.abs(geoLine1.getLength() - geoLine2.getLength()) > delta
				|| geoLine1.getPartCount() != geoLine2.getPartCount())
			return false;
		int count = geoLine1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isPoint2DsEqual(geoLine1.getPart(i), geoLine2.getPart(i)))
				return false;
		}
		return true;
	}

	public static boolean isGeoLine3DEqual(GeoLine3D geoLine3D1,
			GeoLine3D geoLine3D2) {
		return isGeoLine3DEqual(geoLine3D1, geoLine3D2, delta);
	}

	public static boolean isGeoLine3DEqual(GeoLine3D geoLine3D1,
			GeoLine3D geoLine3D2, double delta) {
		if (Math.abs(geoLine3D1.getLength() - geoLine3D2.getLength()) > delta
				|| geoLine3D1.getPartCount() != geoLine3D2.getPartCount())
			return false;
		int count = geoLine3D1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isPoint3DsEqual(geoLine3D1.getPart(i), geoLine3D2.getPart(i)))
				return false;
		}
		return true;
	}

	public static boolean isGeoRegionEqual(GeoRegion geoRegion1,
			GeoRegion geoRegion2) {
		return isGeoRegionEqual(geoRegion1, geoRegion2, delta);
	}

	public static boolean isGeoRegionEqual(GeoRegion geoRegion1,
			GeoRegion geoRegion2, double delta) {
		if (Math.abs(geoRegion1.getPerimeter() - geoRegion2.getPerimeter()) > delta
				|| geoRegion1.getPartCount() != geoRegion2.getPartCount())
			return false;
		int count = geoRegion1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isPoint2DsEqual(geoRegion1.getPart(i), geoRegion2.getPart(i)))
				return false;
		}
		return true;
	}

	public static boolean isGeoRegion3DEqual(GeoRegion3D geoRegion3D1,
			GeoRegion3D geoRegion3D2) {
		return isGeoRegion3DEqual(geoRegion3D1, geoRegion3D2, delta);
	}

	public static boolean isGeoRegion3DEqual(GeoRegion3D geoRegion3D1,
			GeoRegion3D geoRegion3D2, double delta) {
		if (Math.abs(geoRegion3D1.getPerimeter() - geoRegion3D2.getPerimeter()) > delta
				|| geoRegion3D1.getPartCount() != geoRegion3D2.getPartCount())
			return false;
		int count = geoRegion3D1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isPoint3DsEqual(geoRegion3D1.getPart(i), geoRegion3D2
					.getPart(i)))
				return false;
		}
		return true;
	}

	public static boolean isGeoLineMEqual(GeoLineM geoLineM1, GeoLineM geoLineM2) {
		return isGeoLineMEqual(geoLineM1, geoLineM2, delta);
	}

	public static boolean isGeoLineMEqual(GeoLineM geoLineM1,
			GeoLineM geoLineM2, double delta) {
		if (Math.abs(geoLineM1.getLength() - geoLineM2.getLength()) > delta
				|| Math.abs(geoLineM1.getMaxM() - geoLineM2.getMaxM()) > delta
				|| Math.abs(geoLineM1.getMinM() - geoLineM2.getMinM()) > delta
				|| geoLineM1.getPartCount() != geoLineM2.getPartCount())
			return false;
		int count = geoLineM1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isPointMsEqual(geoLineM1.getPart(i), geoLineM2.getPart(i)))
				return false;
		}
		return true;
	}

	public static boolean isGeoTextEqual(GeoText geoText1, GeoText geoText2) {
		return isGeoTextEqual(geoText1, geoText2, delta);
	}

	public static boolean isGeoTextEqual(GeoText geoText1, GeoText geoText2,
			double delta) {
		if (!geoText1.getText().equals(geoText2.getText())
				|| geoText1.getPartCount() != geoText2.getPartCount())
			return false;
		if (!isTextStyleEqual(geoText1.getTextStyle(), geoText1.getTextStyle(),
				delta)) {
			return false;
		}
		int count = geoText1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isTextPartEqual(geoText1.getPart(i), geoText2.getPart(i),
					delta))
				return false;
		}
		return true;
	}

	public static boolean isGeoText3DEqual(GeoText3D geoText3D1,
			GeoText3D geoText3D2) {
		return isGeoText3DEqual(geoText3D1, geoText3D2, delta);
	}

	public static boolean isGeoText3DEqual(GeoText3D geoText3D1,
			GeoText3D geoText3D2, double delta) {
		if (!geoText3D1.getText().equals(geoText3D2.getText())
				|| geoText3D1.getPartCount() != geoText3D2.getPartCount())
			return false;
		if (!isTextStyleEqual(geoText3D1.getTextStyle(), geoText3D2
				.getTextStyle(), delta)) {
			return false;
		}
		int count = geoText3D1.getPartCount();
		for (int i = 0; i < count; i++) {
			if (!isTextPart3DEqual(geoText3D1.getPart(i),
					geoText3D2.getPart(i), delta))
				return false;
		}
		return true;
	}

	public static boolean isGeoArcEqual(GeoArc geoArc1, GeoArc geoArc2) {
		return isGeoArcEqual(geoArc1, geoArc2, delta);
	}

	public static boolean isGeoArcEqual(GeoArc geoArc1, GeoArc geoArc2,
			double delta) {
		if (Math.abs(geoArc1.getCenter().getX() - geoArc2.getCenter().getX()) > delta
				|| Math.abs(geoArc1.getCenter().getY()
						- geoArc2.getCenter().getY()) > delta
				|| Math.abs(geoArc1.getRadius() - geoArc2.getRadius()) > delta
				|| Math.abs(geoArc1.getStartAngle() - geoArc2.getStartAngle()) > delta
				|| Math.abs(geoArc1.getSweepAngle() - geoArc2.getSweepAngle()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoEllipseEqual(GeoEllipse geoEllipse1,
			GeoEllipse geoEllipse2) {
		return isGeoEllipseEqual(geoEllipse1, geoEllipse2, delta);
	}

	public static boolean isGeoEllipseEqual(GeoEllipse geoEllipse1,
			GeoEllipse geoEllipse2, double delta) {
		if (!geoEllipse1.getCenter().equals(geoEllipse2.getCenter())
				|| Math.abs(geoEllipse1.getSemimajorAxis()
						- geoEllipse2.getSemimajorAxis()) > delta
				|| Math.abs(geoEllipse1.getSemiminorAxis()
						- geoEllipse2.getSemiminorAxis()) > delta
				|| Math.abs(geoEllipse1.getRotation()
						- geoEllipse2.getRotation()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoEllipseArcEqual(GeoEllipticArc geoEllipticArc1,
			GeoEllipticArc geoEllipticArc2) {
		return isGeoEllipseArcEqual(geoEllipticArc1, geoEllipticArc2, delta);
	}

	public static boolean isGeoEllipseArcEqual(GeoEllipticArc geoEllipticArc1,
			GeoEllipticArc geoEllipticArc2, double delta) {
		if (!geoEllipticArc1.getCenter().equals(geoEllipticArc2.getCenter())
				|| Math.abs(geoEllipticArc1.getSemimajorAxis()
						- geoEllipticArc2.getSemimajorAxis()) > delta
				|| Math.abs(geoEllipticArc1.getSemiminorAxis()
						- geoEllipticArc2.getSemiminorAxis()) > delta
				|| Math.abs(geoEllipticArc1.getRotation()
						- geoEllipticArc2.getRotation()) > delta
				|| Math.abs(geoEllipticArc1.getStartAngle()
						- geoEllipticArc2.getStartAngle()) > delta
				|| Math.abs(geoEllipticArc1.getSweepAngle()
						- geoEllipticArc2.getSweepAngle()) > delta

		)
			return false;
		return true;
	}

	public static boolean isGeoChordEqual(GeoChord geoChord1, GeoChord geoChord2) {
		return isGeoChordEqual(geoChord1, geoChord2, delta);
	}

	public static boolean isGeoChordEqual(GeoChord geoChord1,
			GeoChord geoChord2, double delta) {
		if (!geoChord1.getCenter().equals(geoChord2.getCenter())
				|| Math.abs(geoChord1.getSemimajorAxis()
						- geoChord2.getSemimajorAxis()) > delta
				|| Math.abs(geoChord1.getSemiminorAxis()
						- geoChord2.getSemiminorAxis()) > delta
				|| Math.abs(geoChord1.getRotation() - geoChord2.getRotation()) > delta
				|| Math.abs(geoChord1.getStartAngle()
						- geoChord2.getStartAngle()) > delta
				|| Math.abs(geoChord1.getSweepAngle()
						- geoChord2.getSweepAngle()) > delta

		)
			return false;
		return true;
	}

	public static boolean isGeoPieEqual(GeoPie geoPie1, GeoPie geoPie2) {
		return isGeoPieEqual(geoPie1, geoPie2, delta);
	}

	public static boolean isGeoPieEqual(GeoPie geoPie1, GeoPie geoPie2,
			double delta) {
		if (!geoPie1.getCenter().equals(geoPie2.getCenter())
				|| Math.abs(geoPie1.getSemimajorAxis()
						- geoPie2.getSemimajorAxis()) > delta
				|| Math.abs(geoPie1.getSemiminorAxis()
						- geoPie2.getSemiminorAxis()) > delta
				|| Math.abs(geoPie1.getRotation() - geoPie2.getRotation()) > delta
				|| Math.abs(geoPie1.getStartAngle() - geoPie2.getStartAngle()) > delta
				|| Math.abs(geoPie1.getSweepAngle() - geoPie2.getSweepAngle()) > delta

		)
			return false;
		return true;
	}

	public static boolean isGeoRectangleEqual(GeoRectangle geoRectangle1,
			GeoRectangle geoRectangle2) {
		return isGeoRectangleEqual(geoRectangle1, geoRectangle2, delta);
	}

	public static boolean isGeoRectangleEqual(GeoRectangle geoRectangle1,
			GeoRectangle geoRectangle2, double delta) {
		if (!geoRectangle1.getCenter().equals(geoRectangle2.getCenter())
				|| Math
						.abs(geoRectangle1.getWidth()
								- geoRectangle2.getWidth()) > delta
				|| Math.abs(geoRectangle1.getHeight()
						- geoRectangle2.getHeight()) > delta
				|| Math.abs(geoRectangle1.getRotation()
						- geoRectangle2.getRotation()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoRoundRectangleEqual(
			GeoRoundRectangle geoRoundRectangle1,
			GeoRoundRectangle geoRoundRectangle2) {
		return isGeoRoundRectangleEqual(geoRoundRectangle1, geoRoundRectangle2,
				delta);
	}

	public static boolean isGeoRoundRectangleEqual(
			GeoRoundRectangle geoRoundRectangle1,
			GeoRoundRectangle geoRoundRectangle2, double delta) {
		if (!geoRoundRectangle1.getCenter().equals(
				geoRoundRectangle2.getCenter())
				|| Math.abs(geoRoundRectangle1.getWidth()
						- geoRoundRectangle2.getWidth()) > delta
				|| Math.abs(geoRoundRectangle1.getHeight()
						- geoRoundRectangle2.getHeight()) > delta
				|| Math.abs(geoRoundRectangle1.getRotation()
						- geoRoundRectangle2.getRotation()) > delta
				|| Math.abs(geoRoundRectangle1.getRadiusX()
						- geoRoundRectangle2.getRadiusX()) > delta
				|| Math.abs(geoRoundRectangle1.getRadiusY()
						- geoRoundRectangle2.getRadiusY()) > delta

		)
			return false;
		return true;
	}

	public static boolean isGeoBSplineEqual(GeoBSpline geoBSpline1,
			GeoBSpline geoBSpline2) {
		return isPoint2DsEqual(geoBSpline1.getControlPoints(), geoBSpline2
				.getControlPoints());
	}

	public static boolean isGeoCurveEqual(GeoCurve geoCurve1, GeoCurve geoCurve2) {
		if (!isPoint2DsEqual(geoCurve1.getControlPoints(), geoCurve2
				.getControlPoints()))
			return false;
		if (Math.abs(geoCurve1.getLength() - geoCurve2.getLength()) > delta)
			return false;
		return true;
	}

	public static boolean isGeoCardinalEqual(GeoCardinal geoCardinal1,
			GeoCardinal geoCardinal2) {
		return isPoint2DsEqual(geoCardinal1.getControlPoints(), geoCardinal2
				.getControlPoints());
	}

	public static boolean isGeoCircleEqual(GeoCircle geoCircle1,
			GeoCircle geoCircle2) {
		return isGeoCircleEqual(geoCircle1, geoCircle2, delta);
	}

	public static boolean isColorsEqual(Colors colors1, Colors colors2) {
		if (colors1.getCount() != colors2.getCount()) {
			return false;
		}
		Color[] _colors1 = colors1.toArray();
		Color[] _colors2 = colors2.toArray();
		for (int i = 0; i < _colors1.length; i++) {
			if (!_colors1[i].equals(_colors2[i])) {
				return false;
			}
		}
		return true;
	}

//	public static boolean isFeature3DsEqual(Feature3Ds feature3Ds1,
//			Feature3Ds feature3Ds2) {
//		if (feature3Ds1.getCount() != feature3Ds2.getCount())
//			return false;
//		for (int i = 0; i < feature3Ds1.getCount(); i++) {
//			System.out.println(feature3Ds1.get(i).getClass());
//		}
//		return true;
//	}

	public static boolean isFileEqual(String filepath1, String filepath2) throws IOException {
		return isFileEqual(filepath1, filepath2, delta);
	}

	public static boolean isFileEqual(String filepath1, String filepath2,
			double delta) throws IOException {
		if (filepath1.equals(filepath2)) {
			return true;
		}

		File f1 = new File(filepath1);
		File f2 = new File(filepath2);
		FileInputStream iisi1 = null;
		FileInputStream iisi2 = null;
		try {

			iisi1 = new FileInputStream(f1);
			iisi2 = new FileInputStream(f2);

			if (Math.abs(iisi1.available() - iisi2.available()) > delta) {
				System.out.println(filepath1 + " and " + filepath2 + " compare false: bytes number not equals");
				return false;
			}

			int i2;
			int i1;
			while ((i1 = iisi1.read()) != -1 && (i2 = iisi2.read()) != -1) {
				if (i1 != i2) {
					System.out.println("File " + filepath1 + ",File" + filepath2 + " compare false:" + ((char) i1) + "," + ((char) i2));
					return false;
				}
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (iisi1 != null) {
				iisi1.close();
			}
			if (iisi2 != null) {
				iisi2.close();
			}
		}
		return true;
	}

	public static boolean isFieldInfosEqual(FieldInfos fieldInfos1,
			FieldInfos fieldInfos2) {
		if (fieldInfos1.getCount() != fieldInfos2.getCount()) {
			return false;
		}
		int count = fieldInfos1.getCount();
		for (int i = 0; i < count; i++) {
			FieldInfo fieldInfo1 = fieldInfos1.get(i);
			String name = fieldInfo1.getName();
			FieldInfo fieldInfo2 = fieldInfos2.get(name);
			if (fieldInfo2 == null)
				return false;
			if (!EqualAssert.isFieldInfoEqual(fieldInfo1, fieldInfo2)) {
				return false;
			}
		}
		return true;
	}

	public static boolean isFieldInfoEqual(FieldInfo fieldInfo1,
			FieldInfo fieldInfo2) {
		if (!fieldInfo1.getName().equalsIgnoreCase(fieldInfo2.getName())) {
			System.out.println("getName不同");
			return false;
		}
		if (!fieldInfo1.getType().equals(fieldInfo2.getType())) {
			System.out.println("getType不同");
			return false;
		}
		if (!fieldInfo1.getCaption().equalsIgnoreCase(fieldInfo2.getCaption())) {
			System.out.println("getCaption不同");
			return false;
		}
		if (!fieldInfo1.getDefaultValue().equals(fieldInfo2.getDefaultValue())) {
			System.out.println("getDefaultValue不同");
			return false;
		}
		// if (!fieldInfo1.getFormat().equals(fieldInfo2.getFormat())) {
		// System.out.println("getFormat不同");
		// return false;
		// }
		// if (fieldInfo1.getMaxLength() != fieldInfo2.getMaxLength()) {
		// System.out.println("getMaxLength不同");
		// return false;
		// }
		// if (fieldInfo1.getPrecision() != fieldInfo2.getPrecision()) {
		// System.out.println("getPrecision不同");
		// return false;
		// }
		// if (fieldInfo1.getScale() != fieldInfo2.getScale()) {
		// System.out.println("getScale不同");
		// return false;
		// }
		if (fieldInfo1.isRequired() != fieldInfo2.isRequired()) {
			System.out.println("isRequired不同");
			return false;
		}
		if (fieldInfo1.isSystemField() != fieldInfo2.isSystemField()) {
			System.out.println("isSystemField不同");
			return false;
		}
		// if (fieldInfo1.isZeroLengthAllowed() != fieldInfo2
		// .isZeroLengthAllowed()) {
		// System.out.println("isZeroLengthAllowed不同");
		// return false;
		// }

		return true;
	}

	public static boolean isGeoCircleEqual(GeoCircle geoCircle1,
			GeoCircle geoCircle2, double delta) {
		if (!geoCircle1.getCenter().equals(geoCircle2.getCenter())
				|| Math.abs(geoCircle1.getRadius() - geoCircle2.getRadius()) > delta)
			return false;
		return true;
	}

	public static boolean isMapEqual(Map map1, Map map2) {

		try {
			String xml1 = map1.toXML();
			String xml2 = map2.toXML();
			int beginIndex = xml1.indexOf("/sml:Name");
			xml1 = xml1.substring(beginIndex);
			beginIndex = xml2.indexOf("/sml:Name");
			xml2 = xml2.substring(beginIndex);
			return map1.equals(map2);
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isMapAssumeEqual(Map map1, Map map2) {
		return isMapAssumeEqual(map1, map2, delta);
	}

	// 地图比较待议
	public static boolean isMapAssumeEqual(Map map1, Map map2, double delta) {

		String xml1 = map1.toXML();
		String xml2 = map2.toXML();
		xml1 = head + xml1 + tail;
		xml2 = head + xml2 + tail;

		try {

			Element root = getRootElement(xml1);
			getElement1List(root);

			root = getRootElement(xml2);
			getElement2List(root);

		} catch (Exception e) {
			return false;
		}

		if (elemList1.size() != elemList2.size())
			return false;

		for (int i = 0; i < elemList1.size(); i++) {

			String string1 = elemList1.get(i).getValue();
			String string2 = elemList2.get(i).getValue();

			if (string1 == null && string2 == null)
				continue;

			if (string1 == null || string2 == null)
				return false;

			try {
				double d1 = Double.valueOf(string1);
				double d2 = Double.valueOf(string2);
				if (Math.abs(d1 - d2) > delta)
					return false;
			} catch (NumberFormatException e) {
				if (!string1.equals(string2))
					return false;
			}
		}

		return true;
	}

	/**
	 * 图像数据缓冲比较
	 * 
	 * @param bufferedImage1
	 * @param bufferedImage2
	 * @return
	 */
	public static boolean isBufferedImageEqual(BufferedImage bufferedImage1,
			BufferedImage bufferedImage2) {
		int width1 = bufferedImage1.getWidth();
		int width2 = bufferedImage2.getWidth();
		if (width1 != width2) {
			return false;
		}
		int height1 = bufferedImage1.getHeight();
		int height2 = bufferedImage2.getHeight();
		if (height1 != height2) {
			return false;
		}
		for (int i = 0; i < width1; i++) {
			for (int j = 0; j < height1; j++) {
				if (bufferedImage1.getRGB(i, j) != bufferedImage2.getRGB(i, j)) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 二维图片对象比较
	 * 
	 * @param geoPicture1
	 * @param geoPicture2
	 * @param delta
	 * @return
	 */
	public static boolean isGeoPictureEqual(GeoPicture geoPicture1,
			GeoPicture geoPicture2, double delta) {
		double width1 = geoPicture1.getWidth();
		double width2 = geoPicture2.getWidth();
		if (width1 - width2 > delta)
			return false;
		double height1 = geoPicture1.getHeight();
		double height2 = geoPicture2.getHeight();
		if (height1 - height2 > delta)
			return false;
		double rotation1 = geoPicture1.getRotation();
		double rotation2 = geoPicture2.getRotation();
		if (rotation1 - rotation2 > delta)
			return false;
		if (!geoPicture1.getCenter().equals(geoPicture2.getCenter()))
			return false;
		if (!isBufferedImageEqual(geoPicture1.getImage(), geoPicture2
				.getImage()))
			return false;
		return true;
	}

	/**
	 * 几何对象比较
	 * 
	 * @param geometry1
	 * @param geometry2
	 * @return
	 */
	public static boolean isGeometryEqual(Geometry geometry1, Geometry geometry2) {
		return isGeometryEqual(geometry1, geometry2, delta);
	}

	public static boolean isGeometryEqual(Geometry geometry1,
			Geometry geometry2, double delta) {
		if(geometry1 == null && geometry2 == null){
			return true;
		}
		if(geometry1 == null || geometry2 == null){
			return false;
		}
		if (geometry1.getType() != geometry2.getType()
				|| geometry1.getID() != geometry2.getID())
			return false;
		if (geometry1.getType().equals(GeometryType.GEOPOINT))
			return isGeoPointEqual((GeoPoint) geometry1, (GeoPoint) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOLINE))
			return isGeoLineEqual((GeoLine) geometry1, (GeoLine) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOREGION))
			return isGeoRegionEqual((GeoRegion) geometry1,
					(GeoRegion) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOTEXT))
			return isGeoTextEqual((GeoText) geometry1, (GeoText) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOLINEM))
			return isGeoLineMEqual((GeoLineM) geometry1, (GeoLineM) geometry2, delta);
		//不知道组件为什么不调用其他类型的比较，先加上
		else if (geometry1.getType().equals(GeometryType.GEOARC))
			return isGeoArcEqual((GeoArc) geometry1, (GeoArc) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOBSPLINE))
			return isGeoBSplineEqual((GeoBSpline) geometry1, (GeoBSpline) geometry2);
		else if (geometry1.getType().equals(GeometryType.GEOCARDINAL))
			return isGeoCardinalEqual((GeoCardinal) geometry1, (GeoCardinal) geometry2);
		else if (geometry1.getType().equals(GeometryType.GEOCHORD))
			return isGeoChordEqual((GeoChord) geometry1, (GeoChord) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOCIRCLE))
			return isGeoCircleEqual((GeoCircle) geometry1, (GeoCircle) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOCONE))
			return isGeoConeEqual((GeoCone) geometry1, (GeoCone) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOCURVE))
			return isGeoCurveEqual((GeoCurve) geometry1, (GeoCurve) geometry2);
		else if (geometry1.getType().equals(GeometryType.GEOELLIPSE))
			return isGeoEllipseEqual((GeoEllipse) geometry1, (GeoEllipse) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOPIE))
			return isGeoPieEqual((GeoPie) geometry1, (GeoPie) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOCOMPOUND))
			return isGeoCompoundEqual((GeoCompound) geometry1, (GeoCompound) geometry2);
		else if (geometry1.getType().equals(GeometryType.GEOLINE3D))
			return isGeoLine3DEqual((GeoLine3D) geometry1, (GeoLine3D) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOREGION3D))
			return isGeoRegion3DEqual((GeoRegion3D) geometry1, (GeoRegion3D) geometry2, delta);
		else if (geometry1.getType().equals(GeometryType.GEOPOINT3D))
			return isGeoPoint3DEqual((GeoPoint3D) geometry1, (GeoPoint3D) geometry2, delta);
		return true;
	}


	private static Element getRootElement(String xml) throws DocumentException {
		Document doc = DocumentHelper.parseText(xml);
		Element elem = doc.getRootElement();
		return elem;
	}

	private static void getElement1List(Element element) {
		List elements = element.elements();
		if (elements.size() == 0) {
			String xpath = element.getPath();
			String value = element.getTextTrim();
			elemList1.add(new Leaf(xpath, value));
		} else {
			for (Iterator it = elements.iterator(); it.hasNext();) {
				Element elem = (Element) it.next();
				getElement1List(elem);
			}
		}
	}

	private static void getElement2List(Element element) {
		List elements = element.elements();
		if (elements.size() == 0) {
			String xpath = element.getPath();
			String value = element.getTextTrim();
			elemList2.add(new Leaf(xpath, value));
		} else {
			for (Iterator it = elements.iterator(); it.hasNext();) {
				Element elem = (Element) it.next();
				getElement2List(elem);
			}
		}
	}

public static double delta = 0.00000001;


	private static List<Leaf> elemList1 = new ArrayList<Leaf>();

	private static List<Leaf> elemList2 = new ArrayList<Leaf>();

	private static String head = "<?xml version=\"1.0\" encoding=\"gb2312\" ?>\n"
			+ "<SuperMapWorkspace xmlns:sml=\"http://www.supermap.com/sml\">\n";

	private static String tail = "\n</SuperMapWorkspace>";
}

class Leaf {

	private String xpath;

	private String value;

	public Leaf(String xpath, String value) {

		this.xpath = xpath;
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getXpath() {
		return xpath;
	}

	public void setXpath(String xpath) {
		this.xpath = xpath;
	}

}
